package com.authine.cloudpivot.ext.applicationservice;

import com.alibaba.cola.dto.RequestContext;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.ext.constants.AppConst;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.dto.ExportquotationGoodsDTO;
import com.authine.cloudpivot.ext.enums.ExportInventedEnum;
import com.authine.cloudpivot.ext.enums.order.OrderCustomerStatusEnum;
import com.authine.cloudpivot.ext.enums.report.ReportType;
import com.authine.cloudpivot.ext.utils.JdbcTemplateUtils;
import com.authine.cloudpivot.ext.utils.StringUtils;
import com.authine.cloudpivot.ext.utils.boQuery.BoQueryUtils;
import com.authine.cloudpivot.ext.utils.system.ReportUtils;
import com.authine.hermes.app.launcher.service.ApplicationService;
import com.authine.mvp.app.launcher.domain.SelectorFormat;
import com.authine.mvp.app.launcher.dto.bo.query.ListBOQuery;
import com.authine.mvp.app.launcher.dto.bo.query.expression.*;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.authine.mvp.app.launcher.rpc.SaveOrUpdateBO;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

@Path("InventedVendorService")
@Slf4j
public class InventedVendorService extends ApplicationService {

    /**
     * 审批拒绝
     *
     * @return
     */
    @Path("rejectApprove")
    @Operation(summary = "审批拒绝", tags = CUSTOM_SERVICE,description = "{data:{id:必填,comment:必填}")
    @POST
    public SingleResponse rejectApprove(SaveOrUpdateBO bo) {


        String id = (String) bo.getData().get("id");


        if (StringUtils.isNull(id) || StringUtils.isNull("comment")) {
            return SingleResponse.buildFailure("-1", "参数不能为空");
        }


        List<Map<String, Object>> list = JdbcTemplateUtils.builder(AppConst.APPROVAL, ModelConst.T_VENDOR_JOIN)
                .selectField(" * ")
                .eq("id", id)
                .queryForList();

        if (list.size() == 0) {
            return SingleResponse.buildFailure("-1", "数据不存在");
        }

        Map<String, Object> data = list.get(0);

        if (!"1".equals(String.valueOf(data.get("architecture_type")))) {
            return SingleResponse.buildFailure("-1", "组织类型错误");
        }

        if (!"2".equals(String.valueOf(data.get("type")))) {
            return SingleResponse.buildFailure("-1", "组织加盟类型错误");
        }

        JdbcTemplateUtils.builder(AppConst.APPROVAL, ModelConst.T_VENDOR_JOIN)
                .putFieldAndVal("deleted",true)
                .eq("id", id)
                .update();

        String comment = (String) bo.getData().get("comment");


        //todo
        //消息推送


        return SingleResponse.buildSuccess();
    }

    /**
     * 虚拟供应商未参与报价 列表
     * <p>
     * ---如果有供应商组织条件条件 organization_id
     * <p>
     * 1.-- 原逻辑:去查组织下的人员,和其父级组织下的人员, 取第一个人员A ,
     * -- 现逻辑:  查虚拟供应商人员绑定表,查询绑定的人员 (binder_id)
     * 2.去查询报价商品 人员=人员A ,获取询价商品id(inquiry_goods_id)
     * 3.查询未参与报价,询价商品id  not in (询价商品id  List);
     *
     * @return
     */
    @Path("inventedNotInvolved")
    @Operation(summary = "虚拟供应商未参与报价", tags = CUSTOM_SERVICE, description = "")
    @POST
    public SingleResponse inventedNotInvolved(ListBOQuery listBOQuery) {


        // 有查询条件
        if (listBOQuery.getCondition() != null) {
            ComplexCondition complexCondition = (ComplexCondition) listBOQuery.getCondition();

            List<Condition> conditions = complexCondition.getConditions();
            //是否有供应商组织查询条件
            Optional<Condition> organization_id = conditions.stream().filter(a -> {
                if (a instanceof SimpleCondition) {
                    return ((SimpleCondition) a).getField().equals("vendor_organization_id");
                } else {
                    return false;
                }
            }).findFirst();
            //有供应商组织查询条件
            if (organization_id.isPresent()) {
                Condition condition = organization_id.get();
                SimpleCondition vendorCond = (SimpleCondition) condition;
                SelectorFormat selectorFormat = JSON.parseObject(JSON.toJSONString(vendorCond.getValue()), SelectorFormat.class);
                if (log.isDebugEnabled()) {
                    log.info("\n\n\n=========有供应商组织查询条件:{}", vendorCond);
                }
                //查询虚拟组织下人员
                List<String> memberIdList = JdbcTemplateUtils.builder(ModelConst.T_BINDING_INVENTED_VENDOR)
                        .selectField(" JSON_UNQUOTE(binder_id -> '$.id') as id ")
                        .eq("JSON_UNQUOTE(organization_id -> '$.id')", selectorFormat.getId())
                        .queryForList(String.class);

                if (!memberIdList.isEmpty()) {
                    //查询虚拟供应商参与的询价商品
                    List<String> inquiryGoodsId = JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_QUOTATION_GOODS)
                            .selectField(" inquiry_goods_id ")
                            .in("JSON_UNQUOTE(member_id -> '$.id')", memberIdList)
                            .queryForList(String.class);
                    if (log.isDebugEnabled()) {
                        log.info("\n\n\n=========查询虚拟供应商参与的询价商品:{}", inquiryGoodsId);
                    }
                    if (!inquiryGoodsId.isEmpty()) {
                        //构建
                        SimpleCondition simpleCondition = new SimpleCondition("id", Operator.NOT_IN, inquiryGoodsId);
                        conditions.add(simpleCondition);
                    }
                }
                //清理掉供应商组织查询条件, 领域没有这个字段, 只是前端到后端的过渡,为了获取 inquiry_goods_id的值
                conditions.remove(condition);
            }
        }
        if (log.isDebugEnabled()) {
            log.debug("\n\n\n=========最终查询条件listBOQuery:{}\n\n\n", listBOQuery);
        }

        return boService.list(listBOQuery);
    }

    /**
     * 虚拟供应商报价列表
     *
     * @param listBOQuery
     * @return
     */
    @Path("inventedQuotedList")
    @Operation(summary = "虚拟供应商报价列表", tags = CUSTOM_SERVICE, description = "")
    @POST
    public SingleResponse inventedQuotedList(ListBOQuery listBOQuery) {
        String vendorOrgName = "vendor_organization_name";

        return inventedModelList(listBOQuery, vendorOrgName);
    }

    /**
     * 虚拟供应商订单商品列表
     *
     * @param listBOQuery
     * @return
     */
    @Path("inventedVendorOrderList")
    @Operation(summary = "虚拟供应商订单商品列表", tags = CUSTOM_SERVICE, description = "")
    @POST
    public SingleResponse inventedVendorOrderList(ListBOQuery listBOQuery) {
        String vendorOrgName = "vendor_organization_name";
        return inventedModelList(listBOQuery, vendorOrgName);
    }

    /**
     * 获取虚拟供应商相关规则领域模模型列表
     * *  做了个前置条件处理:
     * *   -- 获取当前登录人绑定虚拟组织id,追加到报价商品里查询
     *
     * @param listBOQuery
     * @return
     */
    private SingleResponse<BOList> inventedModelList(final ListBOQuery listBOQuery, String vendorOrgName) {
        //查询当前登录人绑定的虚拟供应商
        List<String> orgNameList = JdbcTemplateUtils.builder(ModelConst.T_BINDING_INVENTED_VENDOR)
                .selectField("  JSON_UNQUOTE(organization_id ->'$.name') as name")
                .eq("JSON_UNQUOTE(binder_id -> '$.id')", RequestContext.getCorpLoginId())
                .queryForList(String.class);

        //当前登录人无绑定的虚拟供应商组织, 返回空数据
        if (orgNameList == null || orgNameList.isEmpty()) {
            log.info("\n\n\n=========当前登录人无绑定的虚拟供应商组织, 返回空数据\n\n\n");
            BOList boList = new BOList();
            boList.setData(Collections.emptyList());
            boList.setTotal(0);
            return SingleResponse.of(boList);
        }


        //无条件查询,构建查询条件
        ComplexCondition complexCondition;
        if (listBOQuery.getCondition() == null) {
            complexCondition = new ComplexCondition();
            complexCondition.setNature(Nature.AND);
            listBOQuery.setCondition(complexCondition);
        } else {
            complexCondition = (ComplexCondition) listBOQuery.getCondition();
        }

        //追加查询条件
        SimpleCondition simpleCondition = new SimpleCondition(vendorOrgName, Operator.IN, orgNameList);
        complexCondition.getConditions().add(simpleCondition);

        log.info("\n\n\n=========最终查询条件listBOQuery:{}\n\n\n", listBOQuery);


        return boService.list(listBOQuery);
    }



    /**
     * 虚拟供应商未参与报价/未报价 导出
     *
     *
     * @return
     */
    @Path("exportInvented")
    @Operation(summary = "导出虚拟供应商未参与报价/未报价", tags = CUSTOM_SERVICE, description = "")
    @POST
    public SingleResponse exportInvented(SaveOrUpdateBO saveOrUpdateBO) {
        //导出报表的字段
        String exportField=null;

        //文件位置
        String filePath=null;

        List<String> ids = (List<String>) saveOrUpdateBO.getData().get("ids");
        if (ObjectUtils.isEmpty(ids)) {
            return SingleResponse.buildFailure("-1", "请求参数ids不能为空");
        }

        String fileType = (String) saveOrUpdateBO.getData().get("fileType");
        ReportType reportType = ReportType.get(fileType);

        if (reportType == null) {
            return SingleResponse.buildFailure("-1", "请求参数fileType不能为空");
        }


        ListBOQuery listBOQuery = new ListBOQuery();
        //获取是未报价还是参与报价报表导出
        String exportType = String.valueOf(saveOrUpdateBO.getData().get("exportType"));


        List<Map<String, Object>> data = JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, saveOrUpdateBO.getSchemaCode())
                .selectField("*")
                .in("id", ids)
                .queryForList();


        if (data.isEmpty()) {
            return SingleResponse.buildFailure("-1", "未获取到下载数据");
        }
        //如果是未报价报表导出
        if (ExportInventedEnum.NOT_QUOTED.getCode().equals(exportType)){
            exportField = "{\"inquiryGoodsId\":\"inquiry_goods_id\",\"id\":\"id\",\"vendorOrganizationName\":\"name\",\"brand\":\"brand\",\"model\":\"model\",\"spec\":\"spec\",\"price\":\"price\",\"pretaxPrice\":\"pretax_price\",\"delivery\":\"delivery\",\"num\":\"num\",\"unit\":\"unit\",\"packageNum\":\"package_num\",\"packageUnit\":\"package_unit\",\"freight\":\"freight\",\"pretaxFreight\":\"pretax_freight\",\"taxPayableFreight\":\"tax_payable_freight\",\"taxRate\":\"tax_rate\",\"total\":\"total\",\"taxPayable\":\"tax_payable\",\"pretaxTotal\":\"pretax_total\",\"address\":\"address\",\"description\":\"description\",\"amount\":\"amount\",\"pretaxAmount\":\"pretax_amount\",\"name\":\"name\"}";
            filePath="quotation_goods_report";
        } else {
            exportField = "{\"platformCategoryName\":\"platform_category_name\",\"num\":\"num\",\"sku\":\"sku\",\"barCode\":\"bar_code\",\"description\":\"description\",\"brand\":\"brand\",\"model\":\"model\",\"spec\":\"spec\",\"address\":\"address\",\"name\":\"name\",\"delivery\":\"delivery\",\"unit\":\"unit\",\"packageNum\":\"package_quantity\",\"packageUnit\":\"package_unit\",\"url\":\"url\",\"memo\":\"memo\"}";
            filePath="inquiry_not_involved_report";
        }

        JSONObject exportJson = JSON.parseObject(exportField);
        List<Map<String, Object>> fileData = data.stream().map(m -> {
            Map<String, Object> mf = new HashMap<>();
            for (String key : exportJson.keySet()) {
                mf.put(key, m.get(exportJson.get(key)));
                //报表导出时不转换类型报错
            }
            if (ExportInventedEnum.NOT_QUOTED.getCode().equals(exportType)){
                ExportquotationGoodsDTO dto = JSONObject.parseObject(JSONObject.toJSONString(mf), ExportquotationGoodsDTO.class);
                mf= JSONObject.parseObject(JSONObject.toJSONString(dto), Map.class);
            }
            //转换数组类型

            return mf;
        }).collect(Collectors.toList());


        if (log.isDebugEnabled()) {
            log.debug("======================虚拟供应商{}报表导出参数:reportType={},fileData={}",ExportInventedEnum.getDesc(exportType), reportType.getId(), JSON.toJSONString(fileData));
        }
        ReportUtils.exportReport(filePath, reportType.getId(), fileData);

        return SingleResponse.buildSuccess();

    }

}
